
import {Tree} from 'element-ui'
import debounce from 'lodash/debounce.js'
import lodash from 'lodash'

export default {
  components: {Tree},
  props: {
    value: [Array, String, Number],
    dataUrl: String,
    queryParams: Object,
    multiple: Boolean,
    emptyText: String,
    height: Number,
  },
  data() {
    return {
      selectedKey: '',
      checkedKeys: [],
      treeData: [],
      loading: false,
      errorMsg: '',
      queryTreeData: debounce(this._queryTreeData),
      doDblClick: debounce(this._doDblClick, 200),
      doDblCheck: debounce(this._doDblCheck, 200),
      doCheckChange: debounce(this._doCheckChange, 300),
      initCurrValue: debounce(this._initCurrValue, 300),
      emitOnChange: debounce(this._emitOnChange, 300),
      clickCount: 0
    }
  },
  computed: {
    treeStyle() {
      if (this.height) {
        return {height: this.height + 'px', overflow: 'auto'}
      }
      return null
    }
  },
  created() {
    this.init()
  },
  mounted() {
    this.init()
  },
  watch: {
    value() {
      // console.log('watch/value: ', JSON.stringify(this.value))
      this.initCurrValue()
      this.setTreeChecked()
    },
    dataUrl() {
      this.init()
    },
    queryParams() {
      this.init()
    },
  },
  methods: {
    init() {
      this.selectedKey = ''
      this.checkedKeys = []
      this.treeData = []
      this.initCurrValue()
      this.setTreeChecked()
      this.queryTreeData()
    },
    _initCurrValue() {
      if (this.multiple) {
        this.checkedKeys = this.value || []
      } else {
        this._valueToSelectedKey(this.value)
      }
    },
    _valueToSelectedKey(value) {
      if (lodash.isArray(value)) {
        if (value.length > 0) {
          this.selectedKey = value[0] || ''
        } else {
          this.selectedKey = ''
        }
      } else {
        this.selectedKey = value || ''
      }
    },
    setTreeChecked() {
      if (!this.$refs.tree) {
        return
      }
      this.$nextTick(() => {
        if (this.multiple) {
          this.$refs.tree.setCheckedKeys(this.checkedKeys || [])
        } else {
          this._valueToSelectedKey(this.value)
          this.$refs.tree.setCurrentKey(this.selectedKey)
        }
      })
    },
    _queryTreeData() {
      if (!this.dataUrl) {
        this.errorMsg = '未配置数据接口！'
        return
      }
      this.loading = true
      this.$http.post(this.dataUrl, this.queryParams).then((rs) => {
        this.loading = false
        const result = rs.data
        if (result.success) {
          this.treeData = result.data
        } else {
          this.treeData = []
        }
        this.setTreeChecked()
      })
    },
    _doDblClick(data) {
      // 处理单击
      this.selectedKey = data.id
      if (!this.multiple) {
        this.$emit('input', this.selectedKey)
        this.$emit('onChange', this.selectedKey, data)
      }
      this.$emit('onNodeClick', data)
      // 处理双击
      if (this.clickCount >= 2) {
        const node = this.$refs.tree.store.nodesMap[data.id]
        node.expanded = !node.expanded
      }
      this.clickCount = 0;
    },
    doNodeClick(data) {
      this.clickCount++;
      this.doDblClick(data)
    },
    _checkAll(nodes, checked) {
      nodes.forEach(child => {
        child.checked = checked
        if (child.childNodes && child.childNodes.length) {
          this._checkAll(child.childNodes, checked)
        }
      })
    },
    _doDblCheck(data) {
      if (this.clickCount >= 2) { // 双击勾选全部子节点
        const node = this.$refs.tree.store.nodesMap[data.id]
        node.checked = !node.checked
        this._checkAll(node.childNodes, node.checked)
      }
      this.clickCount = 0;
    },
    doCheck(data) {
      // console.log('doCheck: %s', data.id)
      this.clickCount++;
      this.doDblCheck(data)
    },
    _doCheckChange(data, checked) {
      // console.log('_doCheckChange: %s, %s', data.id, checked)
      this.checkedKeys = this.$refs.tree.getCheckedKeys()
      this.$emit('input', this.checkedKeys)
      this.$emit('onCheckChange', data, checked)
      //
      this.emitOnChange()
    },
    _emitOnChange() {
      let checkedRows = this.$refs.tree.getCheckedNodes()
      this.$emit('onChange', this.checkedKeys, checkedRows)
    }
  }
}